package com.tanqing.ddd.web.domain.impl;

import com.tanqing.ddd.domain.domain.NotRollbackException;
import com.tanqing.ddd.domain.event.EventQueue;
import com.tanqing.ddd.web.domain.BaseEventQueue;
import com.tanqing.ddd.web.domain.CommandInvoker;
import com.tanqing.ddd.web.domain.DomainEventDispatcher;
import com.tanqing.ddd.web.exception.AppException;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.function.Function;

@Service
public class CommandInvokerImpl<R> implements CommandInvoker<R> {

    @Resource
    private DomainEventDispatcher domainEventDispatcher;
    @Transactional(noRollbackFor = NotRollbackException.class)
    public R invoke(Function<EventQueue, R> run) {
        BaseEventQueue baseEventQueue = new BaseEventQueue();
        R apply = null;
        try{
            apply = run.apply(baseEventQueue);
            //事件处理
            this.domainEventDispatcher.dispatchNow(baseEventQueue);
        }catch (NotRollbackException e){
            //事件处理
            this.domainEventDispatcher.dispatchNow(baseEventQueue);
            throw new NotRollbackException(e.getMessage());
        }
        return  apply;
    }
}
